package com.x.wx.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.tobato.fastdfs.FdfsClientConstants;
import com.jfinal.weixin.sdk.api.*;
import com.jfinal.weixin.sdk.api.JsTicketApi.JsApiType;
import com.vdurmont.emoji.EmojiParser;
import com.x.crm.model.Customer;
import com.x.crm.model.CustomerShop;
import com.x.crm.model.Intention;
import com.x.crm.model.IntentionModel;
import com.x.crm.rpc.*;
import com.x.erp.model.Car;
import com.x.erp.model.Shop;
import com.x.erp.rpc.CarRpcService;
import com.x.erp.rpc.ShopRpcService;
import com.x.erp.rpc.UserRpcService;
import com.x.erp.util.Constant;
import com.x.framework.controller.BaseController;
import com.x.framework.controller.ResultCode;
import com.x.framework.controller.ResultModel;
import com.x.framework.redis.XRedisTemplate;
import com.x.wx.conf.WeixinConstants;
import com.x.wx.model.WxAccount;
import com.x.wx.rpc.WxAccountRpcService;
import com.x.wx.rpc.WxUserRpcService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.DigestException;
import java.util.*;

@RestController
public class WxController extends BaseController {

	@Reference
	private CustomerRpcService customerRpcService;// 微信

	@Autowired
	private XRedisTemplate redisClient;

	@Reference
	private CarRpcService carRpcService;// 车辆

	@Reference
	private UserRpcService userRpcService;// 用户

	@Reference
	private ShopRpcService shopRpcService;// 商铺

	@Reference
	private IntentionRpcService intentionRpcService;

	@Reference
	private IntentionModelRpcService intentionModelRpcService;

	@Reference
	private WxUserRpcService wxUserRpcService;

	@Reference
	private CustomerShopRpcService customerShopRpcService;

	@Reference
	private WxAccountRpcService wxAccountRpcService;

	/**
	 * 确认请求来自微信服务器
	 */
	@RequestMapping(value = "/CoreAction", method = { RequestMethod.POST, RequestMethod.GET })
	
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 微信加密签名
		String signature = request.getParameter("signature");
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		// 随机数
		String nonce = request.getParameter("nonce");
		// 随机字符串
		String echostr = request.getParameter("echostr");

		System.out.println(signature);
		System.out.println(timestamp);
		System.out.println(nonce);
		System.out.println(echostr);
		// 742c35f4adee75c49908fdfb626afb2afda543ec
		// 1506447998
		// 3079064726
		// 7321032741832349694

		PrintWriter out = response.getWriter();
		// 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
			System.out.println("weixin check signature success ");
		}
		out.print(echostr);
		out.close();
		out = null;
		return null;
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 统一使用process处理请求
		try {
			execute(request, response);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 处理微信服务器发来的消息
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 将请求、响应的编码均设置为UTF-8（防止中文乱码）
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");

		// 调用核心业务类接收消息、处理消息
		// String respMessage = CoreService.processRequest(request);

		// 响应消息
		PrintWriter out = response.getWriter();
		// out.print(respMessage);
		out.close();
	}

	private CustomerShop insertOrUpdateWxUser(CustomerShop customerShop, String code, String appId, String secret){
		// 通过code换取网页授权access_token
		SnsAccessToken snsAccessToken = SnsAccessTokenApi.getSnsAccessToken(appId, secret, code);
		// String json=snsAccessToken.getJson();
		String token = snsAccessToken.getAccessToken();
		String openId = snsAccessToken.getOpenid();
		// 拉取用户信息(需scope为 snsapi_userinfo)
		ApiResult apiResult = SnsApi.getUserInfo(token, openId);
		if (apiResult.isSucceed()) {
			JSONObject jsonObject = JSON.parseObject(apiResult.getJson());
			String nickname = jsonObject.getString("nickname");
			if(StringUtils.isNotEmpty(nickname)){
				nickname = EmojiParser.removeAllEmojis(nickname);
			}
			// 用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
			int sex = jsonObject.getIntValue("sex");
			String city = jsonObject.getString("city");// 城市
			String province = jsonObject.getString("province");// 省份
			String country = jsonObject.getString("country");// 国家
			String headimgurl = jsonObject.getString("headimgurl");
			Customer customer = new Customer();
			customer.setCustomerOpenId(openId);
			List<Customer> customers = customerRpcService.selectCustomerList(customer);
			customer.setCustomerHeadImage(headimgurl);
			customer.setCustomerGender(sex);
			customer.setCustomerNickname(nickname);
			customer.setCustomerRemark(country + "-" + province + "-" + city);
			if (customers != null && customers.size() > 0) {
				customer.setCustomerId(customers.get(0).getCustomerId());
				customerRpcService.updateCustomer(customer);
				customerShop.setCustomerId(customer.getCustomerId());
				List<CustomerShop> customerShops = customerShopRpcService.selectCustomerShopList(customerShop);
				if(customerShops == null || customerShops.isEmpty()){
					customerShop.setCustomerId(customer.getCustomerId());
					customerShop.setFollowState(1);
					customerShop = customerShopRpcService.insertCustomerShop(customerShop);
				}else{
					customerShop = customerShops.get(0);
				}
			} else {
				customer = customerRpcService.insertCustomer(customer);
				customerShop.setCustomerId(customer.getCustomerId());
				customerShop.setFollowState(1);
				customerShop = customerShopRpcService.insertCustomerShop(customerShop);
			}
			customerShop.setCustomer(customer);
			logger.info("customerShop=" + JSON.toJSONString(customerShop));
			return customerShop;
		}
		return null;
	}

	boolean getUserSubscribeState(String openId){
		ApiResult userRes = UserApi.getUserInfo(openId);
		if(userRes.isSucceed()){
			JSONObject jsonObject = JSON.parseObject(userRes.getJson());
			if(jsonObject.getIntValue("subscribe") == 1){
				return true;
			}
		}
		return false;
	}

	/**
	 * 查询车辆详情
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/wx/getCar", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView getCar(HttpServletRequest request) {
		ModelAndView view = new ModelAndView("redirect:" + Constant.ERP_CONTEXT_PATH + "/mshop/src/cars_detial.html");
		// 用户同意授权，获取code
		String code = request.getParameter("code");
		String state = request.getParameter("state");
		if (code != null) {
			Car car = null;
			if(StringUtils.isNotEmpty(state)) {
				car = new Car();
				car.setCarId(state);
				car = carRpcService.selectCar(car);
			}
			if(car == null){
				return view;
			}
			String marketId = car.getMarketId();
			CustomerShop customerShop = new CustomerShop();
			customerShop.setShopId(car.getShopId());
			customerShop.setMarketId(car.getMarketId());
			ApiConfig apiConfig = getApiConfigByMarketId(marketId);
			customerShop = insertOrUpdateWxUser(customerShop, code, apiConfig.getAppId(), apiConfig.getAppSecret());
			if(customerShop == null){
				return view;
			}
			insertIntention(car, customerShop);
			view.setViewName("redirect:" + Constant.ERP_CONTEXT_PATH + "/mshop/src/cars_detial.html?carId=" + state + "&marketId=" + marketId +"&imgUrl=" + FdfsClientConstants.CLIENT_REQUEST_URL + "&customerShopId=" + customerShop.getCustomerShopId());
		}
		return view;
	}

	/**
	 * 查询车辆详情
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/wx/getShareCar/{shareUserName}/{shareUserMobile}", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView getShareCar(HttpServletRequest request, @PathVariable String shareUserName,  @PathVariable String shareUserMobile) {
		ModelAndView view = new ModelAndView();
		// 用户同意授权，获取code
		String code = request.getParameter("code");
		String state = request.getParameter("state");
		String url = null;
		try {
			shareUserName = URLEncoder.encode(shareUserName, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		if (code != null) {
			Car car = null;
			if(StringUtils.isNotEmpty(state)) {
				car = new Car();
				car.setCarId(state);
				car = carRpcService.selectCar(car);
			}
			if(car == null){
				return view;
			}
			String marketId = car.getMarketId();
			CustomerShop customerShop = new CustomerShop();
			customerShop.setShopId(car.getShopId());
			customerShop.setMarketId(car.getMarketId());
			customerShop.setChannelId(com.x.wx.util.Constant.CRM_CHANNE_ID);
			customerShop.setChannelName(com.x.wx.util.Constant.CRM_CHANNE_NAME);
			ApiConfig apiConfig = getApiConfigByMarketId(marketId);
			customerShop = insertOrUpdateWxUser(customerShop, code, apiConfig.getAppId(), apiConfig.getAppSecret());
			if(customerShop == null){
				return view;
			}
			insertIntention(car, customerShop);
			url = Constant.ERP_CONTEXT_PATH + "/mshop/src/cars_share.html?carId=" + state + "&marketId=" + marketId +"&imgUrl=" + FdfsClientConstants.CLIENT_REQUEST_URL + "&customerShopId=" + customerShop.getCustomerShopId() + "&shareUserName=" + shareUserName + "&shareUserMobile=" + shareUserMobile;
		}else{
			url = Constant.ERP_CONTEXT_PATH + "/mshop/src/cars_share.html?carId=" + state + "&marketId=" + 1 +"&imgUrl=" + FdfsClientConstants.CLIENT_REQUEST_URL + "&customerShopId=&shareUserName=" + shareUserName + "&shareUserMobile=" + shareUserMobile;
		}
		view.setViewName("redirect:" + url);
		return view;
	}

	/**
	 * 插入意向信息
	 * @param car
	 * @param customerShop
	 */
	private void insertIntention(Car car, CustomerShop customerShop) {
		Intention intention = new Intention();
		List<IntentionModel> intentionModelInfo = new ArrayList<>();
		IntentionModel intentionModel = new IntentionModel();
		intentionModel.setCarId(car.getCarId());
		intention.setCustomerShopId(customerShop.getCustomerShopId());
		intentionModel.setIntention(intention);
		List<IntentionModel>  intentionModelList = intentionModelRpcService.selectIntentionCustomerList(intentionModel);
		if (intentionModelList.size() == 0){
			if(customerShop!=null){
				if (customerShop.getFollowState() == 2 && customerShop.getFollowerId() !=null){
					intention.setFollowerId(customerShop.getFollowerId());
					intention.setFollowerName(customerShop.getFollowerName());
					intention.setIntentionState(com.x.crm.util.Constant.INTENTION_DGJ);
					intention.setOpportunityState(com.x.crm.util.Constant.OPPORTUNITY_YCL);
				}else{
					intention.setIntentionState(com.x.crm.util.Constant.INTENTION_DFP);
					intention.setOpportunityState(com.x.crm.util.Constant.OPPORTUNITY_DCL);
				}
			}else{
				return;
			}
			intention.setCustomerMobile(customerShop.getCustomer().getCustomerPhone());
			intention.setIntentionType(1);//购买
			intention.setShopId(car.getShopId());
			intention.setMarketId(car.getMarketId());
			intention.setIsOpportunity(1);
			intention.setOpportunityState(1);
			intention.setIntentionState(1);
			intention.setGetTime(this.getDate(0));
			intention.setCreateTime(this.getDate(0));
			intention.setUpdateTime(this.getDate(0));
			intention.setIntentionChannelId("18080610345715734741160325301255");
			intention.setIntentionChannelName("微店-扫码（大屏）");
			intention.setCustomerContactName("微店扫码客户");
			intentionModel.setSeriesName(car.getSeries().getSeriesName());
			intentionModel.setSeriesId(car.getSeriesId().toString());
			intentionModel.setBrandName(car.getBrand().getBrandName());
			intentionModel.setBrandId(car.getBrandId().toString());
			intentionModel.setCarTitle(car.getCarTitle());
			intentionModel.setCarRetailPrice(car.getCarRetailPrice());
			intentionModel.setCarImageUrl(car.getCarImageUrl());
			intentionModel.setCarState(1);
			intentionModelInfo.add(intentionModel);
			intention.setIntentionModelList(intentionModelInfo);
//			Set<String> wxOpenIds = new HashSet<>();
//			wxOpenIds.add(customerShop.getCustomer().getCustomerOpenId());
//			IntentionMsg intentionMsg = new IntentionMsg(car.getCarId(), car.getShopId(), car.getMarketId(), customerShop.getCustomer().getCustomerPhone(), StringUtils.isNotEmpty(customerShop.getCustomer().getCustomerName())?customerShop.getCustomer().getCustomerNickname():customerShop.getCustomer().getCustomerNickname(), car.getCarTitle(), getDate(getDate(0), "yyyy-MM-dd HH:mm:ss"), wxOpenIds);
			intentionRpcService.insertWxIntentionInfo(intention, null);
		}
	}

	/**
	 * 查询商铺详情
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/wx/getShop", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView getShop(HttpServletRequest request, String marketId ) {
		ModelAndView view = new ModelAndView("redirect:" + Constant.ERP_CONTEXT_PATH + "/mshop/src/home.html?marketId=" + marketId + "&imgUrl=" + FdfsClientConstants.CLIENT_REQUEST_URL);
		// 用户同意授权，获取code
		String code = request.getParameter("code");
		String state = request.getParameter("state");
		if (code != null) {
			Shop shop = null;
			if (StringUtils.isNotEmpty(state)) {
				shop = new Shop();
				shop.setShopId(state);
				List<Shop> shops = shopRpcService.selectShopList(shop);
				if (shops != null && shops.size() > 0) {
					shop = shops.get(0);
				}
			}
			if(shop == null){
				return view;
			}
			CustomerShop customerShop = new CustomerShop();
			customerShop.setShopId(shop.getShopId());
			customerShop.setMarketId(shop.getMarketId());
			ApiConfig apiConfig = getApiConfigByMarketId(shop.getMarketId());
			if(apiConfig == null){
				return view;
			}
			customerShop = insertOrUpdateWxUser(customerShop, code, apiConfig.getAppId(), apiConfig.getAppSecret());
			if (customerShop == null) {
				return view;
			}
//			String marketId = shop.getMarketId();
			view.setViewName("redirect:" + Constant.ERP_CONTEXT_PATH + "/mshop/src/home.html?shopId=" + state + "&marketId=" + marketId + "&imgUrl=" + FdfsClientConstants.CLIENT_REQUEST_URL + "&customerShopId=" + customerShop.getCustomerShopId());
		}
		return view;
	}

	/**
	 * 获取网页分享签名
	 * @param url
	 * @return
	 */
	
	@RequestMapping(value = "/wx/getShareSign", method = { RequestMethod.POST, RequestMethod.GET })
	public ResultModel getShareSign(String url, String marketId) {
		if (StringUtils.isEmpty(url)) {
			return new ResultModel(ResultCode.RESULT_FAIL, "url不能为空！");
		}
		WxAccount wxAccount = new WxAccount();
		wxAccount.setMarketId(marketId);
		wxAccount.setWxAccountState(1);
		List<WxAccount> accounts = wxAccountRpcService.selectWxAccountList(wxAccount);
		ApiConfig apiConfig = null;
		if(accounts != null && !accounts.isEmpty()){
			wxAccount = accounts.get(0);
			apiConfig = ApiConfigKit.getApiConfig(wxAccount.getWxAppId());
		}
		if(apiConfig == null){
			return new ResultModel(ResultCode.RESULT_FAIL, "marketId错误！");
		}
		// 从redis中获取wx_access_token
		JsTicket jsTicket = JsTicketApi.getTicket(JsApiType.jsapi, apiConfig.getAppId());
		String jsapiTicket = jsTicket.getTicket();
		Map<String, Object> map = new HashMap<>();
		map.put("noncestr", SignUtil.CreateNoncestr(16));
		map.put("jsapi_ticket", jsapiTicket);
		map.put("timestamp", System.currentTimeMillis() / 1000);
		map.put("url", url);
		String sign = "";
		try {
			sign = SignUtil.SHA1(map);
		} catch (DigestException e) {
			e.printStackTrace();
		}
		map.put("sign", sign);
		map.put("appId", apiConfig.getAppId());
		map.put("marketShortName", wxAccount.getMarketShortName());
		map.put("wxLogo", wxAccount.getWxLogo());
		map.put("wxQrCode", wxAccount.getWxQrCode());
		map.remove("jsapi_ticket");
		return new ResultModel(ResultCode.RESULT_SUCCESS, "success", map);
	}

	/**
	 * 重定向到微信授权页面
	 * @param action 根据action判断回调页面
	 * @return
	 */
	@RequestMapping(value = "/wx/toWxOpenOauth2", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView toWxOpenOauth2(String action, String state, String marketId, String shareUserName, String shareUserMobile) {
		if(StringUtils.isEmpty(action)){
			action = "erpLogin";
		}
		ModelAndView view = new ModelAndView("");
		ApiConfig apiConfig = getApiConfigByMarketId(marketId);
		String appId = null;
		if(apiConfig == null) {
			appId = WeixinConstants.appId;
		} else {
			appId = apiConfig.getAppId();
		}
		switch (action) {
		case "erpLogin":
			view.setViewName("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + Constant.WX_CONTEXT_PATH + "/controller/wx/getOpenId?appId=" + appId + "&response_type=code&scope=snsapi_userinfo&state=" + action + "#wechat_redirect");
			break;
		case "carDetail":
			view.setViewName("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + Constant.WX_CONTEXT_PATH + "/controller/wx/getCar?marketId=" + marketId + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect");
			break;
		case "shopHome":
			view.setViewName("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + Constant.WX_CONTEXT_PATH + "/controller/wx/getShop?marketId=" + marketId + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect");
			break;
		case "shareCarDetail":
			try {
				shareUserName = URLEncoder.encode(shareUserName, "utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			view.setViewName("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + Constant.WX_CONTEXT_PATH + "/controller/wx/getShareCar/" + shareUserName + "/" + shareUserMobile + "?marketId=" + marketId + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect");
			break;
		default:
			break;
		}
		return view;
	}

	/**
	 * 获取OpenId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/wx/getOpenId", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView getOpenId(HttpServletRequest request, String appId) {
		ModelAndView view = new ModelAndView("redirect:" + Constant.ERP_CONTEXT_PATH + "/wx/openIdLogin.html?wxOpenId=");
		// 用户同意授权，获取code
		String code = request.getParameter("code");
		String state = request.getParameter("state");//根据action判断回调页面
		if(StringUtils.isEmpty(state)){
			state = "erpLogin";
		}
		String openId = "";
		if (code != null) {
			ApiConfig apiConfig = ApiConfigKit.getApiConfig(appId);
			if(apiConfig != null){
				String secret = apiConfig.getAppSecret();
				// 通过code换取网页授权access_token
				SnsAccessToken snsAccessToken = SnsAccessTokenApi.getSnsAccessToken(appId, secret, code);
				openId = snsAccessToken.getOpenid();
			}
		}
		switch (state) {
			case "erpLogin":
				view.setViewName("redirect:" + Constant.ERP_CONTEXT_PATH + "/wx/openIdLogin.html?wxOpenId=" + openId);
				break;
			default:
				break;
		}
		return view;
	}

	private ApiConfig getApiConfigByMarketId(String marketId){
		WxAccount wxAccount = new WxAccount();
		wxAccount.setMarketId(marketId);
		wxAccount.setWxAccountState(1);
		List<WxAccount> accounts = wxAccountRpcService.selectWxAccountList(wxAccount);
		if(accounts != null && !accounts.isEmpty()){
			wxAccount = accounts.get(0);
			return ApiConfigKit.getApiConfig(wxAccount.getWxAppId());
		}
		return ApiConfigKit.getApiConfig(WeixinConstants.appId);
	}
}
